package com.ruoyi.rpt.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.utils.StringUtils;

/**
 * 图表生成工具类
 * 
 * @author ruoyi
 */
@Component
public class ChartGenerator {
    private static final Logger log = LoggerFactory.getLogger(ChartGenerator.class);
    
    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 生成图表数据
     * 
     * @param data 数据列表
     * @param chartType 图表类型
     * @param selectedFieldsJson 选定的字段JSON
     * @return 图表数据
     */
    public Map<String, Object> generateChartData(List<Map<String, Object>> data, String chartType, String selectedFieldsJson) {
        if (data == null || data.isEmpty()) {
            return createEmptyChartData();
        }
        
        try {
            // 解析选定的字段
            List<String> selectedFields = parseSelectedFields(selectedFieldsJson);
            if (selectedFields.isEmpty()) {
                // 如果没有选定字段，则使用数据中的所有字段
                if (!data.isEmpty()) {
                    selectedFields = new ArrayList<>(data.get(0).keySet());
                }
            }
            
            // 根据图表类型生成对应的图表数据
            switch (chartType.toLowerCase()) {
                case "bar":
                    return generateBarChartData(data, selectedFields);
                case "line":
                    return generateLineChartData(data, selectedFields);
                case "pie":
                    return generatePieChartData(data, selectedFields);
                default:
                    return generateBarChartData(data, selectedFields);
            }
        } catch (Exception e) {
            log.error("生成图表数据出错", e);
            return createEmptyChartData();
        }
    }
    
    /**
     * 解析选定的字段JSON
     * 
     * @param selectedFieldsJson 选定的字段JSON
     * @return 字段列表
     */
    private List<String> parseSelectedFields(String selectedFieldsJson) {
        List<String> fields = new ArrayList<>();
        try {
            if (StringUtils.isNotEmpty(selectedFieldsJson)) {
                JsonNode fieldsNode = objectMapper.readTree(selectedFieldsJson);
                if (fieldsNode.isArray()) {
                    for (JsonNode fieldNode : fieldsNode) {
                        fields.add(fieldNode.asText());
                    }
                }
            }
        } catch (Exception e) {
            log.error("解析选定字段出错", e);
        }
        return fields;
    }
    
    /**
     * 生成柱状图数据
     * 
     * @param data 数据列表
     * @param selectedFields 选定的字段
     * @return 柱状图数据
     */
    private Map<String, Object> generateBarChartData(List<Map<String, Object>> data, List<String> selectedFields) {
        Map<String, Object> chartData = new HashMap<>();
        
        if (selectedFields.size() < 2) {
            return createEmptyChartData();
        }
        
        // 第一个字段作为X轴
        String xField = selectedFields.get(0);
        List<String> xAxisData = data.stream()
                .map(row -> row.get(xField) != null ? row.get(xField).toString() : "")
                .collect(Collectors.toList());
        
        // 其余字段作为系列
        List<Map<String, Object>> series = new ArrayList<>();
        for (int i = 1; i < selectedFields.size(); i++) {
            String field = selectedFields.get(i);
            List<Object> seriesData = data.stream()
                    .map(row -> row.get(field))
                    .collect(Collectors.toList());
            
            Map<String, Object> seriesItem = new HashMap<>();
            seriesItem.put("name", field);
            seriesItem.put("type", "bar");
            seriesItem.put("data", seriesData);
            series.add(seriesItem);
        }
        
        chartData.put("xAxis", xAxisData);
        chartData.put("series", series);
        chartData.put("legend", selectedFields.subList(1, selectedFields.size()));
        
        return chartData;
    }
    
    /**
     * 生成折线图数据
     * 
     * @param data 数据列表
     * @param selectedFields 选定的字段
     * @return 折线图数据
     */
    private Map<String, Object> generateLineChartData(List<Map<String, Object>> data, List<String> selectedFields) {
        Map<String, Object> chartData = new HashMap<>();
        
        if (selectedFields.size() < 2) {
            return createEmptyChartData();
        }
        
        // 第一个字段作为X轴
        String xField = selectedFields.get(0);
        List<String> xAxisData = data.stream()
                .map(row -> row.get(xField) != null ? row.get(xField).toString() : "")
                .collect(Collectors.toList());
        
        // 其余字段作为系列
        List<Map<String, Object>> series = new ArrayList<>();
        for (int i = 1; i < selectedFields.size(); i++) {
            String field = selectedFields.get(i);
            List<Object> seriesData = data.stream()
                    .map(row -> row.get(field))
                    .collect(Collectors.toList());
            
            Map<String, Object> seriesItem = new HashMap<>();
            seriesItem.put("name", field);
            seriesItem.put("type", "line");
            seriesItem.put("data", seriesData);
            series.add(seriesItem);
        }
        
        chartData.put("xAxis", xAxisData);
        chartData.put("series", series);
        chartData.put("legend", selectedFields.subList(1, selectedFields.size()));
        
        return chartData;
    }
    
    /**
     * 生成饼图数据
     * 
     * @param data 数据列表
     * @param selectedFields 选定的字段
     * @return 饼图数据
     */
    private Map<String, Object> generatePieChartData(List<Map<String, Object>> data, List<String> selectedFields) {
        Map<String, Object> chartData = new HashMap<>();
        
        if (selectedFields.size() < 2) {
            return createEmptyChartData();
        }
        
        // 第一个字段作为名称，第二个字段作为值
        String nameField = selectedFields.get(0);
        String valueField = selectedFields.get(1);
        
        List<Map<String, Object>> pieData = new ArrayList<>();
        for (Map<String, Object> row : data) {
            Map<String, Object> item = new LinkedHashMap<>();
            item.put("name", row.get(nameField) != null ? row.get(nameField).toString() : "");
            item.put("value", row.get(valueField));
            pieData.add(item);
        }
        
        chartData.put("series", pieData);
        chartData.put("legend", data.stream()
                .map(row -> row.get(nameField) != null ? row.get(nameField).toString() : "")
                .collect(Collectors.toList()));
        
        return chartData;
    }
    
    /**
     * 创建空的图表数据
     * 
     * @return 空的图表数据
     */
    private Map<String, Object> createEmptyChartData() {
        Map<String, Object> chartData = new HashMap<>();
        chartData.put("xAxis", new ArrayList<>());
        chartData.put("series", new ArrayList<>());
        chartData.put("legend", new ArrayList<>());
        return chartData;
    }
} 